package com.work.flow.controller;

import com.work.flow.common.*;
import com.work.flow.dao.MultipartFileParam;
import com.work.flow.feign.ShpFeignService;
import com.work.flow.model.PageModel;
import com.work.flow.service.FileService;
import org.apache.tomcat.util.http.fileupload.servlet.ServletFileUpload;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.URLEncoder;
import java.util.HashMap;
import java.util.Map;

import static java.lang.Thread.sleep;


@RequestMapping("/file/api/v1")
@RestController
public class FileController {
    @Autowired
    FileService fileService;
    @Autowired
    ShpFeignService shpFeignService;
    @Value("${oss.path}")
    String path;

    //    @ApiOperation("大文件分片上传")
    @PostMapping("/chunkUpload")
    public void fileChunkUpload(MultipartFileParam param, HttpServletRequest request, HttpServletResponse response) {

        response.setContentType("text/html;charset=UTF-8");
        // response.setStatus对接前端插件
        //        200, 201, 202: 当前块上传成功，不需要重传。
        //        404, 415. 500, 501: 当前块上传失败，会取消整个文件上传。
        //        其他状态码: 出错了，但是会自动重试上传。
        response.setHeader("Access-Control-Allow-Origin", "*");
        response.setHeader("Access-Control-Allow-Methods", "POST, GET, PUT, OPTIONS, DELETE");

        try {
            /**
             * 判断前端Form表单格式是否支持文件上传
             */
            boolean isMultipart = ServletFileUpload.isMultipartContent(request);
            if (!isMultipart) {
                //这里是我向前端发送数据的代码，可理解为 return 数据; 具体的就不贴了
                System.out.println("不支持的表单格式");
                response.setStatus(404);
                response.getOutputStream().write("不支持的表单格式".getBytes());
            } else {
                param.setTaskId(param.getIdentifier());
                fileService.chunkUploadByMappedByteBuffer(param, path);//service层
                response.setStatus(200);
                response.getWriter().print("上传成功");
            }
            response.getWriter().flush();

        } catch (NotSameFileException e) {
            response.setStatus(501);
        } catch (Exception e) {
            e.printStackTrace();
            System.out.println("上传文件失败");
            response.setStatus(415);
        }
    }


    @GetMapping("/download/{id}")
    public void fileDownById(@PathVariable(value = "id", required = true) String id,
                                HttpServletResponse response) {


        try {

            File fileDir = new File(path + File.separator + id);

            if (!fileDir.isDirectory()) {
                throw new Exception("文件不存在");
            }
            String file = FileTool.fileToZip(path + File.separator + id);
            String fileName = FileTool.getFileName(file);
            // 设置ContentType，响应内容为二进制数据流，编码为utf-8，此处设定的编码是文件内容的编码
            response.setContentType("application/octet-stream;charset=utf-8");
            // 以（Content-Disposition: attachment; filename="filename.jpg"）格式设定默认文件名，设定utf编码，此处的编码是文件名的编码，使能正确显示中文文件名
            response.setHeader("Content-Disposition", "attachment;fileName=" + fileName + ";filename*=utf-8''" + URLEncoder.encode(fileName, "utf-8"));

            // 实现文件下载
            byte[] buffer = new byte[1024];
            FileInputStream fis = null;
            BufferedInputStream bis = null;
            try {
                fis = new FileInputStream(file);
                bis = new BufferedInputStream(fis);
                // 获取字节流
                OutputStream os = response.getOutputStream();
                int i = bis.read(buffer);
                while (i != -1) {
                    os.write(buffer, 0, i);
                    i = bis.read(buffer);
                }
                System.out.println("Download successfully!");
            } catch (Exception e) {
                e.printStackTrace();
                System.out.println("Download failed!");
            } finally {
                if (bis != null) {
                    try {
                        bis.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
                if (fis != null) {
                    try {
                        fis.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }


        } catch (Exception e) {
            e.printStackTrace();
            System.out.println("下载文件失败");
            response.setStatus(500);
        }
    }

    @GetMapping("/downloadByPath")
    public void fileDownByPath(@RequestParam String pathCode,
                                HttpServletResponse response) {

        try {
            String path= Base64Util.decode(pathCode);
            File file = new File(path);

            if (!file.exists()||file.isDirectory()) {
                throw new Exception("文件不存在");
            }
            String fileName = FileTool.getFileName(path);
            if(fileName.endsWith(FileType.SHP.getSuffix())){

                FileTool.fileToZip(file.getParentFile().getAbsolutePath(),response);
            }else {
                // 设置ContentType，响应内容为二进制数据流，编码为utf-8，此处设定的编码是文件内容的编码
                response.setContentType("application/octet-stream;charset=utf-8");
                // 以（Content-Disposition: attachment; filename="filename.jpg"）格式设定默认文件名，设定utf编码，此处的编码是文件名的编码，使能正确显示中文文件名
                response.setHeader("Content-Disposition", "attachment;fileName=" + fileName + ";filename*=utf-8''" + URLEncoder.encode(fileName, "utf-8"));
                response.setHeader("Access-Control-Expose-Headers", "content-disposition");

                // 实现文件下载
                byte[] buffer = new byte[1024];
                FileInputStream fis = null;
                BufferedInputStream bis = null;
                try {
                    fis = new FileInputStream(file);
                    bis = new BufferedInputStream(fis);
                    // 获取字节流
                    OutputStream os = response.getOutputStream();
                    int i = bis.read(buffer);
                    while (i != -1) {
                        os.write(buffer, 0, i);
                        i = bis.read(buffer);
                    }
                    System.out.println("Download successfully!");
                } catch (Exception e) {
                    e.printStackTrace();
                    System.out.println("Download failed!");
                } finally {
                    if (bis != null) {
                        try {
                            bis.close();
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                    }
                    if (fis != null) {
                        try {
                            fis.close();
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                    }
                }
            }



        } catch (Exception e) {
            e.printStackTrace();
            System.out.println("下载文件失败");
            response.setStatus(500);
        }
    }


    @GetMapping("/getCount")
    public R getCount(@RequestParam(required = false) String key){
         try {
             return R.data(fileService.getCount(key));
         }catch (Exception e){
             e.printStackTrace();
             return R.error(e.getMessage());
         }
    }
    @GetMapping("/getList")
    public R getList(){
        try {
            return R.data(fileService.getList());
        }catch (Exception e){
            e.printStackTrace();
            return R.error(e.getMessage());
        }
    }
    @PostMapping("/queryByPage")
    public R queryByPage(@RequestBody PageModel pageModel){
        try {
            return R.data(fileService.queryByPage(pageModel));
        }catch (Exception e){
            e.printStackTrace();
            return R.error(e.getMessage());
        }
    }
    @DeleteMapping("/delete/{id}")
    public R delete(@PathVariable(value = "id", required = true) String id){
        try {
            fileService.deleteById(id);
            return R.ok();
        }catch (Exception e){
            e.printStackTrace();
            return R.error(e.getMessage());
        }
    }
}
